from odoo import fields, models, api, _
from collections import defaultdict
from odoo.exceptions import UserError, ValidationError


class PurchaseRequisitionCreateWizard(models.TransientModel):
    _name = 'purchase.requisition.create.wizard'
    _description = 'Purchase Requisition Create Wizard'

    prm_id = fields.Many2one('purchase.requisition.main.wizard', string='Purchase Requisition Main Wizard',
                             required=True)
    po_id = fields.Many2one('purchase.order', string='Purchase Order')
    pr_line_id = fields.Many2one('purchase.requisition.line', string='Purchase Requisition Line')
    requisition_id = fields.Many2one('purchase.requisition',
                                     string='Purchase Requisition', related='pr_line_id.requisition_id')
    product_id = fields.Many2one('product.template', related='pr_line_id.product_id', string='Product')
    description_en = fields.Text(related="pr_line_id.description_en")
    domain_parent_ids = fields.Many2many('res.partner', string='supplier')
    parent_id = fields.Many2one('res.partner', string='supplier')
    unit_price = fields.Float('Unit Price', digits='Product Unit of Measure')
    product_qty = fields.Float('Quantity', related='pr_line_id.product_qty')  # 请购数量
    qty_received = fields.Float('已处理数量', related='pr_line_id.qty_received')
    do_quantity = fields.Float('下单数量', default=0)

    @api.onchange('do_quantity')
    def onchange_do_quantity(self):
        if self.do_quantity > (self.product_qty - self.qty_received):
            raise UserError('累计采购数量不能大于需求数量')

    @api.onchange('parent_id')
    def onchange_parent_id(self):
        """
        更新价格表
        """
        if self.parent_id:
            seller = self.product_id.seller_ids.filtered(lambda x: x.partner_id.id == self.parent_id.id)
            if seller:
                self.unit_price = seller[0].price
            else:
                self.unit_price = 0
        else:
            self.unit_price = 0

    def confirm_po(self):
        self = self.sudo()
        if not self:
            return
        for record in self:
            product_id = record.product_id
            # 判断产品是否存在于当前PO订单中
            flag = record.po_id.order_line.filtered(lambda l: l.product_id.product_tmpl_id == product_id)
            if len(flag) > 1:
                raise UserError('采购明细同一产品不能存在2条,请合并后保存!!!')
            if flag:
                pr_middle = flag.pr_middle_ids.filtered(lambda x: x.pr_line_id == record.pr_line_id)
                do_quantity = record.do_quantity + flag.product_qty
                if pr_middle:
                    pr_middle.write({'do_quantity': do_quantity})
                    flag.write({'product_qty': do_quantity})
                    record.update_requisition()
                else:
                    flag.write({'pr_middle_ids': [(0, 0, {
                        'pr_line_id': record.pr_line_id.id,
                        'do_quantity': do_quantity,
                    })]})
                    flag.write({'product_qty': do_quantity})
                    record.update_requisition()
            else:
                purchase_id = record.po_id
                pr_middle_ids = [(0, 0, {
                    'pr_line_id': record.pr_line_id.id,
                    'do_quantity': record.do_quantity,
                })]
                purchase_id.write({'order_line': [(0, 0, {
                    'product_id': product_id.product_variant_id.id,
                    'product_qty': record.do_quantity,
                    'product_uom': product_id.uom_po_id.id,
                    'price_unit': record.unit_price,
                    'pr_middle_ids': pr_middle_ids
                })]})
                record.update_requisition()

    def update_requisition(self):
        self.pr_line_id.constraint_do_quantity()
        self.requisition_id.update_state()


class PurchaseRequisitionMainWizard(models.TransientModel):
    _name = 'purchase.requisition.main.wizard'
    _description = 'Purchase Requisition Main Wizard'

    purchase_requisition_ids = fields.Many2many('purchase.requisition', string='Purchase Requisition')
    purchase_requisition_id = fields.Many2one('purchase.requisition', string='Purchase Requisition')
    prc_line_ids = fields.One2many('purchase.requisition.create.wizard', 'prm_id', 'prc_line')

    def confirmation(self):
        self = self.sudo()
        # 根据供应商分组
        supplier_groups = defaultdict(list)
        for pr_line1 in self.prc_line_ids:
            if not pr_line1.parent_id:
                return {
                    'type': 'ir.actions.client',
                    'tag': 'display_notification',
                    'params': {
                        'title': 'Error',
                        'message': _('Please maintain supplier information for product %s' % pr_line1.product_id.name),
                        'sticky': False,  # 设置为 False，表示通知不会一直显示
                        'timeout': 5000,  # 设置通知显示的时间（单位：毫秒），此处为 5 秒
                    }
                }
            if not pr_line1.product_id.product_variant_id:
                return {
                    'type': 'ir.actions.client',
                    'tag': 'display_notification',
                    'params': {
                        'title': 'Error',
                        'type': 'danger',  # warning/danger
                        'message': _('产品变体: %s 不存在或已归档, 无法下单') % pr_line1.product_id.name,
                        'sticky': False,  # 设置为 False，表示通知不会一直显示
                        'timeout': 5000,  # 设置通知显示的时间（单位：毫秒），此处为 5 秒
                    }
                }
            supplier_groups[pr_line1.parent_id].append(pr_line1)
        # 请购单区分, 不可合并请购
        purchase_ids = []
        supplier_list = []
        for supplier, pr_lines in supplier_groups.items():
            # 判断供应商是否配置货币
            if not supplier.property_purchase_currency_id:
                return {
                    'type': 'ir.actions.client',
                    'tag': 'display_notification',
                    'params': {
                        'title': 'Error',
                        'message': _('Supplier: %s currency not configured' % supplier.name),
                        'sticky': False,  # 设置为 False，表示通知不会一直显示
                        'timeout': 5000,  # 设置通知显示的时间（单位：毫秒），此处为 5 秒
                    }
                }
            if not supplier.property_supplier_payment_term_id:
                return {
                    'type': 'ir.actions.client',
                    'tag': 'display_notification',
                    'params': {
                        'title': 'Error',
                        'message': _('Supplier: %s payment term not configured' % supplier.name),
                        'sticky': False,  # 设置为 False，表示通知不会一直显示
                        'timeout': 5000,  # 设置通知显示的时间（单位：毫秒），此处为 5 秒
                    }
                }
            # 同产品分组汇总
            product_groups = defaultdict(list)
            for pr_line2 in pr_lines:
                product_groups[(supplier, pr_line2.product_id)].append(pr_line2)
            order_line = []
            for keys, pr_line3 in product_groups.items():
                supplier, product_id = keys
                do_quantity = sum([i.do_quantity for i in pr_line3])
                line_po_line = []
                for pr in pr_line3:  # 存储请购明细行
                    line_po_line.append((0, 0, {
                        'pr_line_id': pr.pr_line_id.id,
                        'do_quantity': pr.do_quantity,
                    }))
                order_line.append((0, 0, {
                    'product_id': product_id.product_variant_id.id,
                    'product_qty': do_quantity,
                    'product_uom': product_id.uom_po_id.id,
                    'price_unit': pr_line3[0].unit_price,
                    'pr_middle_ids': line_po_line
                }))
            requisition_date = pr_lines[0].pr_line_id.requisition_id.requisition_date
            requisition_ids = pr_lines[0].pr_line_id.requisition_id
            if len(pr_lines) > 1:
                for p in pr_lines:
                    requisition_ids |= p.pr_line_id.requisition_id
            vals = {
                'partner_id': supplier.id,
                'date_order': requisition_date,
                'picking_type_id': self.env.ref('stock.picking_type_in').id,
                'order_line': order_line,
                'requisition_ids': [(6, 0, requisition_ids.ids)],
                'origin': ','.join(requisition_ids.mapped('name')),
                's_remark': ','.join([i for i in requisition_ids.mapped('remark') if i]),
                'currency_id': supplier.property_purchase_currency_id.id,
                'payment_term_id': supplier.property_supplier_payment_term_id.id
            }
            if supplier in supplier_list:
                continue
            purchase_order = self.env['purchase.order'].sudo().create(vals)
            purchase_ids.append(purchase_order.id)
            # # 更改请购单和请购明细状态
            for p in requisition_ids:
                for pi in p.pr_line_ids:
                    pi.constraint_do_quantity()
                p.update_state()
            supplier_list.append(supplier)
        # 根据创建的采购单数量决定返回哪个视图
        if len(purchase_ids) == 1:
            # 如果只有一张采购单，返回表单视图
            return {
                'type': 'ir.actions.act_window',
                'name': 'Purchase Order',
                'res_model': 'purchase.order',
                'view_mode': 'form',
                'res_id': purchase_ids[0],
                'target': 'current',
            }
        else:
            # 如果有多张采购单，返回树形视图
            return {
                'type': 'ir.actions.act_window',
                'name': 'Purchase Orders',
                'res_model': 'purchase.order',
                'view_mode': 'tree,form',
                'domain': [('id', 'in', purchase_ids)],
                'target': 'current',
            }


class RequisitionDefaultDoneWizard(models.TransientModel):
    _name = 'requisition.default.done.wizard'
    _description = '请购单默认完成'

    requisition_id = fields.Many2one('purchase.requisition', string='Purchase Requisition')
    line_ids = fields.One2many('requisition.default.done.line.wizard', 'parent_id')

    def confirmation(self):
        for record in self.line_ids:
            record.pr_line_id.qty_received_virtual = record.do_quantity
            if record.do_quantity <= 0:
                record.pr_line_id.state = 'draft'
            elif record.do_quantity >= record.product_qty:
                record.pr_line_id.state = 'done'
        # 更新状态
        self.requisition_id.update_state()
        if self.requisition_id.state == 'purchasing':
            self.requisition_id.state = 'done'


class RequisitionDefaultDoneLineWizard(models.TransientModel):
    _name = 'requisition.default.done.line.wizard'
    _description = '请购单默认完成'

    parent_id = fields.Many2one('requisition.default.done.wizard')
    pr_line_id = fields.Many2one('purchase.requisition.line', string='PR Line')
    product_id = fields.Many2one('product.template', related='pr_line_id.product_id', string='Product')
    product_qty = fields.Float('Quantity', related='pr_line_id.product_qty')
    do_quantity = fields.Float('完成数量', default=0)
